# import magrittr for piping
library(magrittr)
library(readr)
library(dplyr)
library(plotly)
#read in data to analyze
atp_table <- read_csv("atp_tennis.csv")
Rows: 25362 Columns: 17── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (9): Tournament, Series, Court, Surface, Round, Player_1, Player_2, Winn...
dbl (7): Best of, Rank_1, Rank_2, Pts_1, Pts_2, Odd_1, Odd_2
date (1): Date
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(atp_table)
NA
#plotly tests
atp_dated <- atp_table %>% filter(Date < "2013-01-01")
plot_ly(atp_dated, x = ~Rank_1, y = ~Rank_2,
text = ~Player_1, type = 'scatter', mode = 'markers',
marker = list(size = ~Odd_2, opacity = 0.5))
player_name = "Djokovic N."
atp_table_swapped <- atp_table %>% rename(Player_1 = Player_2, Player_2 = Player_1)
atp_combined <- rbind(atp_table, atp_table_swapped)
atp_combined <- atp_combined[order(atp_combined$Date),]
opponents <- atp_combined %>%
filter(Player_1 == player_name) %>%
select(Player_2) %>%
table(dnn = "name")
opponents %<>% as.data.frame()
opponents <- opponents[rev(order(opponents$Freq)),]
fig <- plot_ly(opponents, x = ~name, y = ~Freq, type = 'bar')
fig
player_results = list()
players = c("Djokovic N.", "Nadal R.")
for(player in players){
# grab the relevant player ratings
atp_player_result <- atp_combined %>%
filter(Player_1 == player) %>%
# grab names ranks and dates
select(Rank_1 | Rank_2 | Date | Player_1 | Player_2)
# add the player result to the list
player_results[[length(player_results)+1]] = atp_player_result
}
ggplot(bind_rows(player_results, .id="data_frame"),
aes(x=Date, y=Rank_1, group = Player_1)) +
geom_line(aes(color = Player_1)) +
scale_y_reverse() +
labs(y = "Ranking", title = "Player Ranking over Time")

library(ggplot2)
ggplot(head(opponents,10), aes(x=name, y = Freq))

library(shiny)
player_selections <<- data.frame( player =
c(atp_table$Player_1,
atp_table$Player_2)) %>%
# used https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/table
# need the column name to be the same every time
table(dnn = list("name")) %>%
as.data.frame(responseName = "freq")
# https://stackoverflow.com/questions/62716572/selectinput-category-selection
# Stéphane Laurent
# https://shiny.posit.co/r/reference/shiny/latest/updateselectinput
# for context (lets me know onInitialize is running as JavaScript)
onInitialize <- "
function(){
var select = this.$input[0];
this.$dropdown_content.on('mousedown', function(e){
e.preventDefault();
return false;
}).on('click', '.optgroup-header', function(e){
var options = $(this).parent().find('.option');
var items = [];
options.each(function(i, opt){items.push($(opt).data('value'));});
var selections = select.selectize.items;
select.selectize.setValue(items.concat(selections));
});
}
"
shinyApp(
ui = fluidPage(
selectizeInput("state", "Choose a player:",
player_selections,
multiple = TRUE,
options = list(
onInitialize = I(onInitialize)
)
)
),
server = function(input, output){}
)
Listening on http://127.0.0.1:5536
NA
library(GGally)
library(igraph)
player = "Djokovic N."
atp_player_result <- atp_combined %>%
filter(Player_1 == player) %>%
# grab names ranks and dates
select(Player_2)
#make a data frame with the frequency of occurrences
network_table_df <- atp_player_result %>%
table(dnn = list("name")) %>%
as.data.frame(responseName = "freq")
#order by frequency
network_table_df <- network_table_df[order(network_table_df$freq, decreasing = TRUE),]
simple_edge_df <- data.frame(
from = rep(player,length(network_table_df$name)),
to = network_table_df$name,
weight = network_table_df$freq
)
net <- graph_from_data_frame(simple_edge_df)
p <- ggnet2(simplify(net), size = simple_edge_df$weight, label = TRUE)
Error in set_node(node.size, "node.size") : incorrect node.size length
length(atp_player_result$Player_2)
[1] 632
nodes <- data.frame(id = unique(atp_combined$Player_1))
edges <- data.frame(from = atp_table$Player_1, to = atp_table$Player_2)
visNetwork(nodes, edges, width = "100%")
LS0tDQp0aXRsZTogIkluZGl2aWR1YWwgUHJvamVjdCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KYXV0aG9yOiBTcGVuY2VyIFNraWRtb3JlDQotLS0NCg0KDQoNCmBgYHtyfQ0KIyBpbXBvcnQgbWFncml0dHIgZm9yIHBpcGluZw0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShwbG90bHkpDQojcmVhZCBpbiBkYXRhIHRvIGFuYWx5emUNCmF0cF90YWJsZSA8LSByZWFkX2NzdigiYXRwX3Rlbm5pcy5jc3YiKQ0KaGVhZChhdHBfdGFibGUpDQoNCmBgYA0KYGBge3J9DQojcGxvdGx5IHRlc3RzDQphdHBfZGF0ZWQgPC0gYXRwX3RhYmxlICU+JSBmaWx0ZXIoRGF0ZSA8ICIyMDEzLTAxLTAxIikNCnBsb3RfbHkoYXRwX2RhdGVkLCB4ID0gflJhbmtfMSwgeSA9IH5SYW5rXzIsIA0KICAgICAgICB0ZXh0ID0gflBsYXllcl8xLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KHNpemUgPSB+T2RkXzIsIG9wYWNpdHkgPSAwLjUpKQ0KYGBgDQoNCmBgYHtyfQ0KcGxheWVyX25hbWUgPSAiRGpva292aWMgTi4iDQphdHBfdGFibGVfc3dhcHBlZCA8LSBhdHBfdGFibGUgJT4lIHJlbmFtZShQbGF5ZXJfMSA9IFBsYXllcl8yLCBQbGF5ZXJfMiA9IFBsYXllcl8xKQ0KYXRwX2NvbWJpbmVkIDwtIHJiaW5kKGF0cF90YWJsZSwgYXRwX3RhYmxlX3N3YXBwZWQpDQphdHBfY29tYmluZWQgPC0gYXRwX2NvbWJpbmVkW29yZGVyKGF0cF9jb21iaW5lZCREYXRlKSxdDQpvcHBvbmVudHMgPC0gYXRwX2NvbWJpbmVkICU+JQ0KICBmaWx0ZXIoUGxheWVyXzEgPT0gcGxheWVyX25hbWUpICU+JQ0KICBzZWxlY3QoUGxheWVyXzIpICU+JQ0KICB0YWJsZShkbm4gPSAibmFtZSIpDQpvcHBvbmVudHMgJTw+JSBhcy5kYXRhLmZyYW1lKCkNCm9wcG9uZW50cyA8LSBvcHBvbmVudHNbcmV2KG9yZGVyKG9wcG9uZW50cyRGcmVxKSksXQ0KZmlnIDwtIHBsb3RfbHkob3Bwb25lbnRzLCB4ID0gfm5hbWUsIHkgPSB+RnJlcSwgdHlwZSA9ICdiYXInKQ0KZmlnDQpgYGANCmBgYHtyfQ0KcGxheWVyX3Jlc3VsdHMgPSBsaXN0KCkNCnBsYXllcnMgPSBjKCJEam9rb3ZpYyBOLiIsICJOYWRhbCBSLiIpDQpmb3IocGxheWVyIGluIHBsYXllcnMpew0KICAjIGdyYWIgdGhlIHJlbGV2YW50IHBsYXllciByYXRpbmdzDQogIGF0cF9wbGF5ZXJfcmVzdWx0IDwtIGF0cF9jb21iaW5lZCAlPiUNCiAgICBmaWx0ZXIoUGxheWVyXzEgPT0gcGxheWVyKSAlPiUNCiAgICAjIGdyYWIgbmFtZXMgcmFua3MgYW5kIGRhdGVzDQogICAgc2VsZWN0KFJhbmtfMSB8IFJhbmtfMiB8IERhdGUgfCBQbGF5ZXJfMSB8IFBsYXllcl8yKQ0KICAjIGFkZCB0aGUgcGxheWVyIHJlc3VsdCB0byB0aGUgbGlzdA0KICBwbGF5ZXJfcmVzdWx0c1tbbGVuZ3RoKHBsYXllcl9yZXN1bHRzKSsxXV0gPSBhdHBfcGxheWVyX3Jlc3VsdA0KfQ0KZ2dwbG90KGJpbmRfcm93cyhwbGF5ZXJfcmVzdWx0cywgLmlkPSJkYXRhX2ZyYW1lIiksDQogICAgICAgYWVzKHg9RGF0ZSwgeT1SYW5rXzEsIGdyb3VwID0gUGxheWVyXzEpKSArDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBQbGF5ZXJfMSkpICsNCiAgc2NhbGVfeV9yZXZlcnNlKCkgKw0KICBsYWJzKHkgPSAiUmFua2luZyIsIHRpdGxlID0gIlBsYXllciBSYW5raW5nIG92ZXIgVGltZSIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpnZ3Bsb3QoaGVhZChvcHBvbmVudHMsMTApLCBhZXMoeD1uYW1lLCB5ID0gRnJlcSkpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHNoaW55KQ0KcGxheWVyX3NlbGVjdGlvbnMgPDwtIGRhdGEuZnJhbWUoIHBsYXllciA9IA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYyhhdHBfdGFibGUkUGxheWVyXzEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHBfdGFibGUkUGxheWVyXzIpKSAlPiUNCiAgIyB1c2VkIGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9iYXNlL3ZlcnNpb25zLzMuNi4yL3RvcGljcy90YWJsZQ0KICAjIG5lZWQgdGhlIGNvbHVtbiBuYW1lIHRvIGJlIHRoZSBzYW1lIGV2ZXJ5IHRpbWUNCiAgdGFibGUoZG5uID0gbGlzdCgibmFtZSIpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZShyZXNwb25zZU5hbWUgPSAiZnJlcSIpDQoNCiMgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjI3MTY1NzIvc2VsZWN0aW5wdXQtY2F0ZWdvcnktc2VsZWN0aW9uDQojIFN0w6lwaGFuZSBMYXVyZW50DQojIGh0dHBzOi8vc2hpbnkucG9zaXQuY28vci9yZWZlcmVuY2Uvc2hpbnkvbGF0ZXN0L3VwZGF0ZXNlbGVjdGlucHV0DQojIGZvciBjb250ZXh0IChsZXRzIG1lIGtub3cgb25Jbml0aWFsaXplIGlzIHJ1bm5pbmcgYXMgSmF2YVNjcmlwdCkNCm9uSW5pdGlhbGl6ZSA8LSAiDQpmdW5jdGlvbigpew0KICB2YXIgc2VsZWN0ID0gdGhpcy4kaW5wdXRbMF07DQogIHRoaXMuJGRyb3Bkb3duX2NvbnRlbnQub24oJ21vdXNlZG93bicsIGZ1bmN0aW9uKGUpew0KICAgIGUucHJldmVudERlZmF1bHQoKTsgDQogICAgcmV0dXJuIGZhbHNlOw0KICB9KS5vbignY2xpY2snLCAnLm9wdGdyb3VwLWhlYWRlcicsIGZ1bmN0aW9uKGUpew0KICAgIHZhciBvcHRpb25zID0gJCh0aGlzKS5wYXJlbnQoKS5maW5kKCcub3B0aW9uJyk7DQogICAgdmFyIGl0ZW1zID0gW107DQogICAgb3B0aW9ucy5lYWNoKGZ1bmN0aW9uKGksIG9wdCl7aXRlbXMucHVzaCgkKG9wdCkuZGF0YSgndmFsdWUnKSk7fSk7DQogICAgdmFyIHNlbGVjdGlvbnMgPSBzZWxlY3Quc2VsZWN0aXplLml0ZW1zOw0KICAgIHNlbGVjdC5zZWxlY3RpemUuc2V0VmFsdWUoaXRlbXMuY29uY2F0KHNlbGVjdGlvbnMpKTsNCiAgfSk7DQp9DQoiDQoNCnNoaW55QXBwKA0KICB1aSA9IGZsdWlkUGFnZSgNCiAgICBzZWxlY3RpemVJbnB1dCgic3RhdGUiLCAiQ2hvb3NlIGEgcGxheWVyOiIsDQogICAgICAgICAgICAgICAgICAgcGxheWVyX3NlbGVjdGlvbnMsDQogICAgICAgICAgICAgICAgICAgbXVsdGlwbGUgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgIG9uSW5pdGlhbGl6ZSA9IEkob25Jbml0aWFsaXplKQ0KICAgICAgICAgICAgICAgICAgICkNCiAgICApDQogICksDQogIHNlcnZlciA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQpe30NCikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoR0dhbGx5KQ0KbGlicmFyeShpZ3JhcGgpDQpwbGF5ZXIgPSAiRGpva292aWMgTi4iIA0KICAgIGF0cF9wbGF5ZXJfcmVzdWx0IDwtIGF0cF9jb21iaW5lZCAlPiUNCiAgICAgIGZpbHRlcihQbGF5ZXJfMSA9PSBwbGF5ZXIpICU+JQ0KICAgICAgIyBncmFiIG5hbWVzIHJhbmtzIGFuZCBkYXRlcw0KICAgICAgc2VsZWN0KFBsYXllcl8yKQ0KICAgICNtYWtlIGEgZGF0YSBmcmFtZSB3aXRoIHRoZSBmcmVxdWVuY3kgb2Ygb2NjdXJyZW5jZXMNCiAgICBuZXR3b3JrX3RhYmxlX2RmIDwtIGF0cF9wbGF5ZXJfcmVzdWx0ICU+JQ0KICAgICAgdGFibGUoZG5uID0gbGlzdCgibmFtZSIpKSAlPiUNCiAgICAgIGFzLmRhdGEuZnJhbWUocmVzcG9uc2VOYW1lID0gImZyZXEiKQ0KICAgICNvcmRlciBieSBmcmVxdWVuY3kNCiAgICBuZXR3b3JrX3RhYmxlX2RmIDwtIG5ldHdvcmtfdGFibGVfZGZbb3JkZXIobmV0d29ya190YWJsZV9kZiRmcmVxLCBkZWNyZWFzaW5nID0gVFJVRSksXQ0KICAgIHNpbXBsZV9lZGdlX2RmIDwtIGRhdGEuZnJhbWUoDQogICAgICBmcm9tID0gcmVwKHBsYXllcixsZW5ndGgobmV0d29ya190YWJsZV9kZiRuYW1lKSksDQogICAgICB0byA9IG5ldHdvcmtfdGFibGVfZGYkbmFtZSwNCiAgICAgIHdlaWdodCA9IG5ldHdvcmtfdGFibGVfZGYkZnJlcQ0KICAgICkNCiAgICANCiAgICBuZXQgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKHNpbXBsZV9lZGdlX2RmKQ0KICAgIG5ldCAldiUgIndlaWdodCIgPSBpZmVsc2UobmV0ICV2JSAicGhvbm8iID09ICJ2b3dlbCIsICJzdGVlbGJsdWUiLCAidG9tYXRvIikNCiAgICBwIDwtIGdnbmV0MihzaW1wbGlmeShuZXQpLCBzaXplID0gc2ltcGxlX2VkZ2VfZGYkd2VpZ2h0LCBsYWJlbCA9IFRSVUUpDQogICAgZ2dwbG90bHkocCkNCmBgYA0KYGBge3J9DQpyZXAocGxheWVyLGxlbmd0aChhdHBfcGxheWVyX3Jlc3VsdCRQbGF5ZXJfMikpDQpgYGANCg0KYGBge3J9DQpub2RlcyA8LSBkYXRhLmZyYW1lKGlkID0gdW5pcXVlKGF0cF9jb21iaW5lZCRQbGF5ZXJfMSkpDQplZGdlcyA8LSBkYXRhLmZyYW1lKGZyb20gPSBhdHBfdGFibGUkUGxheWVyXzEsIHRvID0gYXRwX3RhYmxlJFBsYXllcl8yKQ0KdmlzTmV0d29yayhub2RlcywgZWRnZXMsIHdpZHRoID0gIjEwMCUiKQ0KYGBgDQoNCg0K